home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / SeqPups / appsrc / cap.src / CAP2.c next >
Text File  |  1996-07-05  |  63KB  |  2,421 lines

  1.  
  2. /* dgg -- for use as Mac child-app */
  3. #define MACINTOSH 1
  4.  
  5. /* CONTIG ASSEMBLY PROGRAM (CAP)
  6.  
  7.    copyright (c) 1991    Xiaoqiu Huang
  8.    The distribution of the program is granted provided no charge
  9.    is made and the copyright notice is included.
  10.  
  11.    Proper attribution of the author as the source of the software
  12.    would be appreciated:
  13.    "A Contig Assembly Program Based on Sensitive Detection of
  14.    Fragment Overlaps" (submitted to Genomics, 1991)
  15.     Xiaoqiu Huang
  16.     Department of Computer Science
  17.     Michigan Technological University
  18.     Houghton, MI 49931
  19.         E-mail: huang@cs.mtu.edu
  20.  
  21.    The CAP program uses a dynamic programming algorithm to compute
  22.    the maximal-scoring overlapping alignment between two fragments.
  23.    Fragments in random orientations are assembled into contigs by a
  24.    greedy approach in order of the overlap scores. CAP is efficient
  25.    in computer memory: a large number of arbitrarily long fragments
  26.    can be assembled. The time requirement is acceptable; for example,
  27.    CAP took 4 hours to assemble 1015 fragments of a total of 252 kb
  28.    nucleotides on a Sun SPARCstation SLC. The program is written in C
  29.    and runs on Sun workstations.
  30.  
  31.    Below is a description of the parameters in the #define section of CAP.
  32.    Two specially chosen sets of substitution scores and indel penalties
  33.    are used by the dynamic programming algorithm: heavy set for regions
  34.    of low sequencing error rates and light set for fragment ends of high
  35.    sequencing error rates. (Use integers only.)
  36.     Heavy set:             Light set:
  37.  
  38.     MATCH     =  2             MATCH     =  2
  39.     MISMAT    = -6             LTMISM    = -3
  40.     EXTEND    =  4             LTEXTEN   =  2
  41.  
  42.     In the initial assembly, any overlap must be of length at least OVERLEN,
  43.     and any overlap/containment must be of identity percentage at least
  44.     PERCENT. After the initial assembly, the program attempts to join
  45.     contigs together using weak overlaps. Two contigs are merged if the
  46.     score of the overlapping alignment is at least CUTOFF. The value for
  47.     CUTOFF is chosen according to the value for MATCH.
  48.  
  49.     DELTA is a parameter in necessary conditions for overlap/containment.
  50.     Those conditions are used to quickly reject pairs of fragments that
  51.     could not possibly have an overlap/containment relationship.
  52.     The dynamic programming algorithm is only applied to pairs of fragments
  53.     that pass the screening. A large value for DELTA means stringent
  54.     conditions, where the value for DELTA is a real number at least 8.0.
  55.  
  56.     POS5 and POS3 are fragment positions such that the 5' end between base 1
  57.     and base POS5, and the 3' end after base POS3 are of high sequencing
  58.     error rates, say more than 5%. For mismatches and indels occurring in
  59.     the two ends, light penalties are used.
  60.  
  61.     A file of input fragments looks like:
  62. >G019uabh
  63. ATACATCATAACACTACTTCCTACCCATAAGCTCCTTTTAACTTGTTAAA
  64. GTCTTGCTTGAATTAAAGACTTGTTTAAACACAAAAATTTAGAGTTTTAC
  65. TCAACAAAAGTGATTGATTGATTGATTGATTGATTGATGGTTTACAGTAG
  66. GACTTCATTCTAGTCATTATAGCTGCTGGCAGTATAACTGGCCAGCCTTT
  67. AATACATTGCTGCTTAGAGTCAAAGCATGTACTTAGAGTTGGTATGATTT
  68. ATCTTTTTGGTCTTCTATAGCCTCCTTCCCCATCCCCATCAGTCTTAATC
  69. AGTCTTGTTACGTTATGACTAATCTTTGGGGATTGTGCAGAATGTTATTT
  70. TAGATAAGCAAAACGAGCAAAATGGGGAGTTACTTATATTTCTTTAAAGC
  71. >G028uaah
  72. CATAAGCTCCTTTTAACTTGTTAAAGTCTTGCTTGAATTAAAGACTTGTT
  73. TAAACACAAAATTTAGACTTTTACTCAACAAAAGTGATTGATTGATTGAT
  74. TGATTGATTGATGGTTTACAGTAGGACTTCATTCTAGTCATTATAGCTGC
  75. TGGCAGTATAACTGGCCAGCCTTTAATACATTGCTGCTTAGAGTCAAAGC
  76. ATGTACTTAGAGTTGGTATGATTTATCTTTTTGGTCTTCTATAGCCTCCT
  77. TCCCCATCCCATCAGTCT
  78. >G022uabh
  79. TATTTTAGAGACCCAAGTTTTTGACCTTTTCCATGTTTACATCAATCCTG
  80. TAGGTGATTGGGCAGCCATTTAAGTATTATTATAGACATTTTCACTATCC
  81. CATTAAAACCCTTTATGCCCATACATCATAACACTACTTCCTACCCATAA
  82. GCTCCTTTTAACTTGTTAAAGTCTTGCTTGAATTAAAGACTTGTTTAAAC
  83. ACAAAATTTAGACTTTTACTCAACAAAAGTGATTGATTGATTGATTGATT
  84. GATTGAT
  85. >G023uabh
  86. AATAAATACCAAAAAAATAGTATATCTACATAGAATTTCACATAAAATAA
  87. ACTGTTTTCTATGTGAAAATTAACCTAAAAATATGCTTTGCTTATGTTTA
  88. AGATGTCATGCTTTTTATCAGTTGAGGAGTTCAGCTTAATAATCCTCTAC
  89. GATCTTAAACAAATAGGAAAAAAACTAAAAGTAGAAAATGGAAATAAAAT
  90. GTCAAAGCATTTCTACCACTCAGAATTGATCTTATAACATGAAATGCTTT
  91. TTAAAAGAAAATATTAAAGTTAAACTCCCCTATTTTGCTCGTTTTTGCTT
  92. ATCTAAAATACATTCTGCACAATCCCCAAAGATTGATCATACGTTAC
  93. >G006uaah
  94. ACATAAAATAAACTGTTTTCTATGTGAAAATTAACCTANNATATGCTTTG
  95. CTTATGTTTAAGATGTCATGCTTTTTATCAGTTGAGGAGTTCAGCTTAAT
  96. AATCCTCTAAGATCTTAAACAAATAGGAAAAAAACTAAAAGTAGAAAATG
  97. GAAATAAAATGTCAAAGCATTTCTACCACTCAGAATTGATCTTATAACAT
  98. GAAATGCTTTTTAAAAGAAAATATTAAAGTTAAACTCCCC
  99.    A string after ">" is the name of the following fragment.
  100.    Only the five upper-case letters A, C, G, T and N are allowed
  101.    to appear in fragment data. No other characters are allowed.
  102.    A common mistake is the use of lower case letters in a fragment.
  103.  
  104.    To run the program, type a command of form
  105.  
  106.     cap  file_of_fragments  
  107.  
  108.    The output goes to the terminal screen. So redirection of the
  109.    output into a file is necessary. The output consists of three parts:
  110.    overview of contigs at fragment level, detailed display of contigs
  111.    at nucleotide level, and consensus sequences.
  112.    '+' = direct orientation; '-' = reverse complement
  113.    The output of CAP on the sample input data looks like:
  114.  
  115. #Contig 1
  116.  
  117. #G022uabh+(0)
  118. TATTTTAGAGACCCAAGTTTTTGACCTTTTCCATGTTTACATCAATCCTGTAGGTGATTG
  119. GGCAGCCATTTAAGTATTATTATAGACATTTTCACTATCCCATTAAAACCCTTTATGCCC
  120. ATACATCATAACACTACTTCCTACCCATAAGCTCCTTTTAACTTGTTAAAGTCTTGCTTG
  121. AATTAAAGACTTGTTTAAACACAAAA-TTTAGACTTTTACTCAACAAAAGTGATTGATTG
  122. ATTGATTGATTGATTGAT
  123. #G028uaah+(145)
  124. CATAAGCTCCTTTTAACTTGTTAAAGTCTTGCTTGAATTAAAGACTTGTTTAAACACAAA
  125. A-TTTAGACTTTTACTCAACAAAAGTGATTGATTGATTGATTGATTGATTGATGGTTTAC
  126. AGTAGGACTTCATTCTAGTCATTATAGCTGCTGGCAGTATAACTGGCCAGCCTTTAATAC
  127. ATTGCTGCTTAGAGTCAAAGCATGTACTTAGAGTTGGTATGATTTATCTTTTTGGTCTTC
  128. TATAGCCTCCTTCCCCATCCC-ATCAGTCT
  129. #G019uabh+(120)
  130. ATACATCATAACACTACTTCCTACCCATAAGCTCCTTTTAACTTGTTAAAGTCTTGCTTG
  131. AATTAAAGACTTGTTTAAACACAAAAATTTAGAGTTTTACTCAACAAAAGTGATTGATTG
  132. ATTGATTGATTGATTGATGGTTTACAGTAGGACTTCATTCTAGTCATTATAGCTGCTGGC
  133. AGTATAACTGGCCAGCCTTTAATACATTGCTGCTTAGAGTCAAAGCATGTACTTAGAGTT
  134. GGTATGATTTATCTTTTTGGTCTTCTATAGCCTCCTTCCCCATCCCCATCAGTCTTAATC
  135. AGTCTTGTTACGTTATGACT-AATCTTTGGGGATTGTGCAGAATGTTATTTTAGATAAGC
  136. AAAA-CGAGCAAAAT-GGGGAGTT-A-CTT-A-TATTT-CTTT-AAA--GC
  137. #G023uabh-(426)
  138. GTAACGT-ATGA-TCAATCTTTGGGGATTGTGCAGAATGT-ATTTTAGATAAGCAAAAAC
  139. GAGCAAAATAGGGGAGTTTAACTTTAATATTTTCTTTTAAAAAGCATTTCATGTTATAAG
  140. ATCAATTCTGAGTGGTAGAAATGCTTTGACATTTTATTTCCATTTTCTACTTTTAGTTTT
  141. TTTCCTATTTGTTTAAGATCGTAGAGGATTATTAAGCTGAACTCCTCAACTGATAAAAAG
  142. CATGACATCTTAAACATAAGCAAAGCATATTTTTAGGTTAATTTTCACATAGAAAACAGT
  143. TTATTTTATGTGAAATTCTATGTAGATATACTATTTTTTTGGTATTTATT
  144. #G006uaah-(496)
  145. GGGGAGTTTAACTTTAATATTTTCTTTTAAAAAGCATTTCATGTTATAAGATCAATTCTG
  146. AGTGGTAGAAATGCTTTGACATTTTATTTCCATTTTCTACTTTTAGTTTTTTTCCTATTT
  147. GTTTAAGATCTTAGAGGATTATTAAGCTGAACTCCTCAACTGATAAAAAGCATGACATCT
  148. TAAACATAAGCAAAGCATATNNT-AGGTTAATTTTCACATAGAAAACAGTTTATTTTATG
  149. T
  150.  
  151.  
  152.  
  153. Slight modifications by S. Smith on Mon Feb 17 10:18:34 EST 1992.
  154. These changes allow for command line arguements for several
  155. of the hard coded parameters, as well as a slight modification to
  156. the output routine to support GDE format.  Changes are commented
  157. as:
  158.  
  159. Mod by S.S.
  160.  
  161. */
  162.  
  163.  
  164. #pragma segment Cap2
  165.  
  166. #include   <stdio.h>
  167. #include   <stdlib.h>
  168.  
  169.  
  170. int OVERLEN;        /* Minimum length of any overlap */
  171. float PERCENT;      /* Minimum identity percentage of any overlap */
  172. #define  CUTOFF    50            /* cutoff score for overlap or containment */
  173. #define  DELTA     9.0            /* Jump increment in check for overlap */
  174. #define  MATCH     2            /* score of a match */
  175. #define  MISMAT   -6            /* score of a mismatch */
  176. #define  LTMISM   -3            /* light score of a mismatch */
  177. #define  OPEN      0            /* gap open penalty */
  178. #define  EXTEND    4            /* gap extension penalty */
  179. #define  LTEXTEN   2            /* light gap extension penalty */
  180. #define  POS5      30            /* Sequencing errors often occur before base POS5 */
  181. #define  POS3      475            /* Sequencing errors often occur after base POS3 */
  182. #define  LINELEN   60        /* length of one printed line */
  183. #define  NAMELEN   20        /* length of printed fragment name */
  184. #define  TUPLELEN  4            /* Maximum length of words for lookup table */
  185. #define  SEQLEN    2000            /* initial size of an array for an output fragment */
  186.  
  187. static int over_len;
  188. static float per_cent;
  189. typedef struct OVERLAP        /* of 5' and 3' segments */
  190. {  
  191.     int    number;    /* index of 3' segment   */
  192.     int    host;        /* index of 5' segment   */
  193.     int    ind;        /* used in reassembly */
  194.     int    stari;    /* start position of 5' suffix */
  195.     int    endi;        /* end position of 5' suffix   */
  196.     int    starj;    /* start position of 3' prefix */
  197.     int    endj;        /* end position of 3' prefix   */
  198.     short   orienti;    /* orientation of 5' segment: 0= rev. */
  199.     short   orientj;    /* orientation of 3' segment: 0= rev. */
  200.     int    score;    /* score of overlap alignment */
  201.     int    length;    /* length of alignment      */
  202.     int    match;    /* number of matches in alignment */
  203.     short   kind;    /* 0 = containment; 1 = overlap   */
  204.     int    *script;    /* script for constructing alignment */
  205.     struct  OVERLAP  *next; 
  206. } over, *overptr;
  207. struct SEG
  208. {  
  209.     char    *name;    /* name string */
  210.     int     len;        /* length of segment name */
  211.     char    *seq;    /* segment sequence */
  212.     char    *rev;    /* reverse complement */
  213.     int     length;    /* length of sequence */
  214.     short   kind;    /* 0 = contain; 1 = overlap */
  215.     int     *lookup;    /* lookup table */
  216.     int     *pos;    /* location list */
  217.     overptr list;    /* list of overlapping edges */
  218. } *segment;    /* array of segment records */
  219. int   seg_num;                  /* The number of segments   */
  220. overptr   *edge;        /* set of overlapping edges */
  221. int   edge_num;                 /* The number of overlaps */
  222. struct CONS            /* 1 = itself; 0 = reverse complement */
  223. {  
  224.     short   isfive[2];    /* is 5' end free? */
  225.     short   isthree[2];    /* is 3' end free? */
  226.     short   orient[2];    /* orientation of 3' segment */
  227.     int     group;    /* contig serial number */
  228.     int     next[2];    /* pointer to 3' adjacent segment */
  229.     int     other;    /* the other end of the contig   */
  230.     int     child;    /* for the containment tree   */
  231.     int     brother;
  232.     int     father;
  233.     overptr node[2];    /* pointers to overlapping edges */
  234. } *contigs;  /* list of contigs */
  235. struct TTREE            /* multiple alignment tree */
  236. {  
  237.     short   head;    /* head = 1 means the head of a contig */
  238.     short   orient;    /* orientation */
  239.     int     begin;    /* start position of previous segment */
  240.     int     *script;    /* alignment script */
  241.     int     size;    /* length of script */
  242.     int     next;    /* list of overlap segments */
  243.     int     child;    /* list of child segments */
  244.     int     brother;    /* list of sibling segments */
  245. }  *mtree;
  246. int   vert[128];        /* converted digits for 'A','C','G','T' */
  247. int   vertc[128];        /* for reverse complement */
  248. int   tuple;            /* tuple = TUPLELEN - 1 */
  249. int  base[TUPLELEN];        /* locations of a lookup table */
  250. int  power[TUPLELEN];        /* powers of 4 */
  251. typedef struct OUT
  252.     char  *line;        /* one print line */
  253.     char  *a;        /* pointer to slot in line */
  254.     char  c;        /* current char */
  255.     char  *seq;        /* pointer to sequence */
  256.     int   length;        /* length of segment */
  257.     int   id;        /* index of segment */
  258.     int   *s;        /* pointer to script vector */
  259.     int   size;        /* size of script vector */
  260.     int   op;        /* current operation */
  261.     char  name[NAMELEN+2];/* name of segment */
  262.     short done;        /* indicates if segment is done */
  263.     int   loc;        /* position of next segment symbol */
  264.     char  kind;        /* type of next symbol of segment */
  265.     char  up;        /* type of upper symbol of operation */
  266.     char  dw;        /* type of lower symbol of operation */
  267.     int   offset;        /* relative to consensus sequence */
  268.     int   linesize;    /* size of array line */
  269.     struct  OUT *child;    /* pointer to child subtree */
  270.     struct  OUT *brother;    /* pointer to brother node */
  271.     struct  OUT *link;    /* for operation linked list */
  272.     struct  OUT *father;    /* pointer to father node */
  273. }  row, *rowptr;    /* node for segment */
  274. rowptr *work;            /* a set of working segments */
  275. rowptr head, tail;        /* first and last nodes of op list */
  276. struct VX
  277. {  
  278.     int     id;            /* Segment index */
  279.     short   kind;        /* overlap or containment */
  280.     overptr list;        /* list of overlapping edges */
  281. } *piece;        /* array of segment records */
  282. char  *allconsen, *allconpt;        /* Storing consensus sequences */
  283.  
  284. /* dgg patches for mac use */
  285.  
  286. char
  287. nuccomp( symbol)  char symbol;
  288. {
  289.     switch ( symbol ) { 
  290.         case 'A' : return  'T'; 
  291.         case 'a' : return  't'; 
  292.         case 'T' : return  'A'; 
  293.         case 't' : return  'a'; 
  294.         case 'C' : return  'G'; 
  295.         case 'c' : return  'g'; 
  296.         case 'G' : return  'C'; 
  297.         case 'g' : return  'c'; 
  298.         default  : return  symbol; 
  299.         }
  300. }
  301.  
  302. char *ckalloc(int amount); /* for borland c */
  303.  
  304.  
  305. typedef    char    cvec[128];
  306.  
  307. FILE* fout;    /* output file */
  308.  
  309.  
  310. #ifdef MACINTOSH
  311. // use with ChildApp.c
  312.  
  313. int RealMain( int argc, char *argv[])
  314.  
  315. #else
  316.  
  317. int main(argc, argv) 
  318. int argc; char *argv[];
  319. #endif
  320.     int   M;                    /* Sequence length */
  321. /* dgg -- make smaller arrays for mac */
  322. /*    int   V[128][128], Q,R;         
  323.     int   V1[128][128], R1;     
  324. */
  325.     cvec  *V, *V1;
  326.     short    Q,R, R1;     
  327.     int   total;                    /* Total of segment lengths */
  328.     int   number;                         /* The number of segments   */
  329.     char  *sequence;            /* Storing all segments     */
  330.     char  *reverse;            /* Storing all reverse segments */
  331.     int   symbol, prev;            /* The next character         */
  332.     FILE *Ap, *ckopen();                  /* For the sequence file      */
  333.     char *ckalloc();            /* space-allocating function  */
  334.     register int  i, j, k;        /* index variables          */
  335.     /* Mod by S.S. */
  336.     int jj;
  337.     short  heading;            /* 1: heading; 0: sequence    */
  338.     
  339.     /*
  340. *    Mod by S.S. & dgg
  341. *
  342.     if ( argc != 2 )
  343.         fatalf("The proper form of command is: \n%s file_of_fragments",
  344.              argv[0]);
  345. */
  346.     if ( argc < 5 ) {
  347.         short i;
  348.         for (i= 0; i<argc; i++)  fprintf(stderr, "arg[%d]=%s \n", i, argv[i]);
  349.         fatalf("usage: %s file_of_fragments output_file MIN_OVERLAP PERCENT_MATCH",
  350.             argv[0]);
  351.          }
  352.     sscanf(argv[3],"%d",&OVERLEN);
  353.     sscanf(argv[4],"%d",&jj);
  354.     PERCENT = (float)jj/100.0;
  355.     if(PERCENT < 0.25) PERCENT = 0.25;
  356.     if(PERCENT > 1.0) PERCENT = 1.0;
  357.     if(OVERLEN < 1) OVERLEN = 1;
  358.     if(OVERLEN > 100) OVERLEN = 100;
  359.  
  360.     if (argv[2] == "stdout" || argv[2] == "-") fout= NULL;
  361.     else fout = fopen( argv[2], "w");
  362.     if (!fout) fout = stdout;
  363.  
  364.     /* determine number of segments and total lengths */
  365.     j = 0;
  366.  
  367.     Ap = ckopen(argv[1], "r");
  368.     prev = '\n';
  369.     for (total = 3, number = 0; ( symbol = fgetc(Ap)) != EOF ; total++ )
  370.     { 
  371.         if ( symbol == '>' && prev == '\n' )
  372.             number++;
  373.         prev = symbol;
  374.     }
  375.     (void)    fclose(Ap);
  376.  
  377.     /* dgg - allocate space for arrays */
  378.     /* for (i=0; i<128; i++) V[i]= ( char *) ckalloc( 128 * sizeof(char)); NO NO */
  379.     V= ( cvec *) ckalloc( 128 * 128 * sizeof(char)); /* !! yes */
  380.     V1= ( cvec *) ckalloc( 128 * 128 * sizeof(char));
  381.  
  382.     total += number * 20;
  383.     /* allocate space for segments */
  384.     sequence = ( char * ) ckalloc( total * sizeof(char));
  385.     reverse = ( char * ) ckalloc( total * sizeof(char));
  386.     allconpt = allconsen = ( char * ) ckalloc( total * sizeof(char));
  387.     segment = ( struct SEG * ) ckalloc( number * sizeof(struct SEG));
  388.  
  389.     /* read the segments into sequence */
  390.     M = 0;
  391.     Ap = ckopen(argv[1], "r");
  392.     number = -1;
  393.     heading = 0;
  394.     prev = '\n';
  395.     for ( i = 0, k = total ; ( symbol = fgetc(Ap)) != EOF ; )
  396.     { 
  397.         if ( symbol != '\n' )
  398.         { 
  399.             sequence[++i] = symbol;
  400.             /* reverse[--k] = nuccomp( symbol); */
  401.             switch ( symbol )
  402.             { 
  403.             case 'A' : 
  404.                 reverse[--k] = 'T'; 
  405.                 break;
  406.             case 'a' : 
  407.                 reverse[--k] = 't'; 
  408.                 break;
  409.             case 'T' : 
  410.                 reverse[--k] = 'A'; 
  411.                 break;
  412.             case 't' : 
  413.                 reverse[--k] = 'a'; 
  414.                 break;
  415.             case 'C' : 
  416.                 reverse[--k] = 'G'; 
  417.                 break;
  418.             case 'c' : 
  419.                 reverse[--k] = 'g'; 
  420.                 break;
  421.             case 'G' : 
  422.                 reverse[--k] = 'C'; 
  423.                 break;
  424.             case 'g' : 
  425.                 reverse[--k] = 'c'; 
  426.                 break;
  427.             default  : 
  428.                 reverse[--k] = symbol; 
  429.                 break;
  430.             }
  431.         }
  432.         if ( symbol == '>' && prev == '\n' )
  433.         { 
  434.             heading = 1;
  435.             if ( number >= 0 )
  436.             { 
  437.                 segment[number].length = i - j - 1;
  438.                 segment[number].rev = &(reverse[k]);
  439.                 if ( i - j - 1 > M ) M = i - j -1;
  440.             }
  441.             number++;
  442.             j = i;
  443.             segment[number].name = &(sequence[i]);
  444.             segment[number].kind = 1;
  445.             segment[number].list = 0;
  446.         }
  447.         if ( heading && symbol == '\n' )
  448.         { 
  449.             heading = 0;
  450.             segment[number].len = i - j;
  451.             segment[number].seq = &(sequence[i]);
  452.             j = i;
  453.         }
  454.  
  455.         prev = symbol;
  456.     }
  457.     segment[number].length = i - j;
  458.     reverse[--k] = '>';
  459.     segment[number].rev = &(reverse[k]);
  460.     if ( i - j > M ) M = i - j;
  461.     seg_num = ++number;
  462.     (void)    fclose(Ap);
  463.  
  464.     Q = OPEN;
  465.     R = EXTEND;
  466.     R1 = LTEXTEN;
  467.     /* set match and mismatch weights */
  468.     for ( i = 0; i < 128 ; i++ )
  469.         for ( j = 0; j < 128 ; j++ )
  470.             if ((i|32) == (j|32) )
  471.                 V[i][j] = V1[i][j] = MATCH;
  472.             else
  473.             { 
  474.                 V[i][j] = MISMAT;
  475.                 V1[i][j] = LTMISM;
  476.             }
  477.     for ( i = 0; i < 128 ; i++ )
  478.         V['N'][i] = V[i]['N'] = MISMAT + 1;
  479.     V1['N']['N'] = MISMAT + 1;
  480.  
  481.     over_len = OVERLEN;
  482.     per_cent = PERCENT;
  483.     edge_num = 0;
  484.     fprintf(stderr,"\nINIT"); INIT(M);
  485.     fprintf(stderr,"\nMAKE"); MAKE();
  486.     fprintf(stderr,"\nPAIR"); PAIR(V,V1,Q,R,R1);
  487.     fprintf(stderr,"\nASSEM"); ASSEM();
  488.     fprintf(stderr,"\nREPAIR"); REPAIR();
  489.     fprintf(stderr,"\nFORM_TREE"); FORM_TREE();
  490.     /* GRAPH(); */
  491.     fprintf(stderr,"\nSHOW\n"); SHOW();  
  492.     fclose(fout); /* dgg */
  493. }
  494.  
  495. static char  (*varray)[128];            /* substitution scores */
  496. static int  q, r;            /* gap penalties */
  497. static int  qr;                /* qr = q + r */
  498. static char  (*v1)[128];            /* light substitution scores */
  499. static int  r1;                /* light extension penalty */
  500. static int  qr1;            /* qr1 = q + r1 */
  501.  
  502. static int   SCORE;
  503. static int   STARI;
  504. static int   STARJ;
  505. static int   ENDI;
  506. static int   ENDJ;
  507.  
  508. static int  *CC, *DD;            /* saving matrix scores */
  509. static int  *RR, *SS;             /* saving start-points */
  510. static int   *S;            /* saving operations for diff */
  511.  
  512. /* The following definitions are for function diff() */
  513.  
  514. int   diff();
  515. static int   zero = 0;                /* int  type zero        */
  516.  
  517. #define gap(k)  ((k) <= 0 ? 0 : q+r*(k))    /* k-symbol indel score */
  518.  
  519. static int  *sapp;                /* Current script append ptr */
  520. static int   last;                /* Last script op appended */
  521.  
  522. static int  no_mat;                 /* number of matches */
  523.  
  524. static int  no_mis;                 /* number of mismatches */
  525.  
  526. static int  al_len;                 /* length of alignment */
  527. /* Append "Delete k" op */
  528. #define DEL(k)                \
  529. { al_len += k;                \
  530.   if (last < 0)                \
  531.     last = sapp[-1] -= (k);        \
  532.   else                    \
  533.     last = *sapp++ = -(k);        \
  534. }
  535. /* Append "Insert k" op */
  536. #define INS(k)                \
  537. { al_len += k;                \
  538.   if (last < 0)                \
  539.     { sapp[-1] = (k); *sapp++ = last; }    \
  540.   else                    \
  541.     last = *sapp++ = (k);        \
  542. }
  543.  
  544. /* Append "Replace" op */
  545. #define REP                 \
  546. { last = *sapp++ = 0;             \
  547.   al_len += 1;                \
  548. }
  549.  
  550. INIT(M) int  M;
  551.     register  int   j;            /* row and column indices */
  552.     char *ckalloc();            /* space-allocating function */
  553.  
  554.     /* allocate space for all vectors */
  555.     j = (M + 1) * sizeof(int );
  556.     CC = ( int  * ) ckalloc(j);
  557.     DD = ( int  * ) ckalloc(j);
  558.     RR = ( int  * ) ckalloc(j);
  559.     SS = ( int  * ) ckalloc(j);
  560.     S = ( int  * ) ckalloc(2 * j);
  561. }
  562.  
  563. /* Make a lookup table for words of lengths up to TUPLELEN in each sequence.
  564.    The value of a word is used as an index to the table.  */
  565. MAKE()
  566.     int   hash[TUPLELEN];        /* values of words of lengths up to TUPLELEN */
  567.     int   *table;            /* pointer to a lookup table */
  568.     int   *loc;            /* pointer to a table of sequence locations */
  569.     int   size;            /* size of a lookup table */
  570.     int   limit, digit, step;    /* temporary variables  */
  571.     register  int  i, j, k, p, q;    /* index varibles */
  572.     char *ckalloc();        /* space-allocating function */
  573.     char *A;            /* pointer to a sequence */
  574.     int  M;            /* length of a sequence */
  575.  
  576.     tuple = TUPLELEN - 1;
  577.     for ( i = 0; i < 128; i++ )
  578.         vert[i] = 4;
  579.     vert['A'] = vert['a'] = 0;
  580.     vert['C'] = vert['c'] = 1;
  581.     vert['G'] = vert['g'] = 2;
  582.     vert['T'] = vert['t'] = 3;
  583.     vertc['A'] = vertc['a'] = 3;
  584.     vertc['C'] = vertc['c'] = 2;
  585.     vertc['G'] = vertc['g'] = 1;
  586.     vertc['T'] = vertc['t'] = 0;
  587.     for ( i = 0, j = 1, size = 0; i <= tuple ; i++, j *= 4 )
  588.     {  
  589.         base[i] = size;
  590.         power[i] = j;
  591.         size = ( size + 1 ) * 4;
  592.     }
  593.     for ( j = 0; j <= tuple; j++ )
  594.         hash[j] = 0;
  595.     /* make a lookup table for each sequence */
  596.     for ( i = 0; i < seg_num ; i++ )
  597.     { 
  598.         A = segment[i].seq;
  599.         M = segment[i].length;
  600.         table = segment[i].lookup = (int  * ) ckalloc(size * sizeof(int ));
  601.         loc = segment[i].pos = (int  * ) ckalloc((M + 1) * sizeof(int ));
  602.         for ( j = 0; j < size; j++ )
  603.             table[j] = 0;
  604.         for ( k = 0, j = 1; j <= M; j++ )
  605.             if ( ( digit = vert[A[j]] ) != 4 )
  606.             { 
  607.                 for ( p = tuple; p > 0; p-- )
  608.                     hash[p] = 4 * (hash[p-1] + 1) + digit;
  609.                 hash[0] = digit;
  610.                 step = j - k;
  611.                 limit = tuple <= step ? tuple : step;
  612.                 for ( p = 0; p < limit; p++ )
  613.                     if ( ! table[(q = hash[p])] )  table[q] = 1;
  614.                 if ( step > tuple )
  615.                 { 
  616.                     loc[(p = j - tuple)] = table[(q = hash[tuple])];
  617.                     table[q] = p;
  618.                 }
  619.             }
  620.             else
  621.                 k = j;
  622.     }
  623. }
  624.  
  625. /* Perform pair-wise comparisons of sequences. The sequences not
  626.    satisfying the necessary condition for overlap are rejected quickly.
  627.    Those that do satisfy the condition are verified with a dynamic
  628.    programming algorithm to see if overlaps exist. */
  629. PAIR(V,V1,Q,R,R1) char  V[][128],V1[][128],Q,R,R1;
  630.     int  endi, endj, stari, starj;    /* endpoint and startpoint */
  631.  
  632.     short orienti, orientj;        /* orientation of segments */
  633.     short iscon;                /* containment condition   */
  634.     int   score;               /* the max score */
  635.     int  count, limit;            /* temporary variables     */
  636.  
  637.     register  int   i, j, d;        /* row and column indices  */
  638.     char *ckalloc();            /* space-allocating function */
  639.     int  rl, cl;
  640.     char *A, *B;
  641.     int  M, N;
  642.     overptr node1;
  643.     int  total;                /* total number of pairs */
  644.     int  hit;                /* number of pairs satisfying cond. */
  645.     int  CHECK();
  646.  
  647.     varray = V;
  648.     q = Q;
  649.     r = R;
  650.     qr = q + r;
  651.     v1 = V1;
  652.     r1 = R1;
  653.     qr1 = q + r1;
  654.     total = hit = 0;
  655.     limit = 2 * ( seg_num - 1 );
  656.     for ( orienti = 0, d = 0; d < limit ; d++ )
  657.     { 
  658.         i = d / 2;
  659.         orienti = 1 - orienti;
  660.         A = orienti ? segment[i].seq : segment[i].rev;
  661.         M = segment[i].length;
  662.         for ( j = i+1; j < seg_num ; j++ )
  663.         { 
  664.             B = segment[j].seq;
  665.             orientj = 1;
  666.             N = segment[j].length;
  667.             total += 1;
  668.             if ( CHECK(orienti, i, j) )
  669.             { 
  670.                 hit += 1;
  671.                 SCORE = 0;
  672.                 big_pass(A,B,M,N,orienti,orientj);
  673.                 if ( SCORE )
  674.                 { 
  675.                     score = SCORE;
  676.                     stari = ++STARI;
  677.                     starj = ++STARJ;
  678.                     endi = ENDI;
  679.                     endj = ENDJ;
  680.                     rl = endi - stari + 1;
  681.                     cl = endj - starj + 1;
  682.                     sapp = S;
  683.                     last = 0;
  684.                     al_len = no_mat = no_mis = 0;
  685.                     (void) diff(&A[stari]-1, &B[starj]-1,rl,cl,q,q);
  686.                     iscon = stari == 1 && endi == M || starj == 1 && endj == N;
  687.                     if ( no_mat >= al_len * per_cent &&
  688.                         ( al_len >= over_len || iscon ) )
  689.                     { 
  690.                         node1 = ( overptr ) ckalloc( (int ) sizeof(over));
  691.                         if ( iscon )
  692.                             node1->kind = 0;        /* containment */
  693.                         else
  694.                         { 
  695.                             node1->kind = 1; 
  696.                             edge_num++; 
  697.                         }    /* overlap */
  698.                         if ( endi == M && ( endj != N || starj != 1 ) ) /*i is 5'*/
  699.                         { 
  700.                             node1->number = j;
  701.                             node1->host = i;
  702.                             node1->stari = stari;
  703.                             node1->endi = endi;
  704.                             node1->orienti = orienti;
  705.                             node1->starj = starj;
  706.                             node1->endj = endj;
  707.                             node1->orientj = orientj;
  708.                         }
  709.                         else    /* j is 5' */
  710.                         { 
  711.                             node1->number = i;
  712.                             node1->host = j;
  713.                             node1->stari = starj;
  714.                             node1->endi = endj;
  715.                             node1->orienti = orientj;
  716.                             node1->starj = stari;
  717.                             node1->endj = endi;
  718.                             node1->orientj = orienti;
  719.                         }
  720.                         node1->score = score;
  721.                         node1->length = al_len;
  722.                         node1->match = no_mat;
  723.                         count = node1->number == i ? j : i;
  724.                         node1->next = segment[count].list;
  725.                         segment[count].list = node1;
  726.                         if ( ! node1->kind )
  727.                             segment[count].kind = 0;
  728.                     }
  729.                 }
  730.             }
  731.         }
  732.     }
  733. }
  734.  
  735. /* Return 1 if two sequences satisfy the necessary condition for overlap,
  736.    and 0 otherwise. Parameters first and second are the indices of segments,
  737.    and parameter orient indicates the orientation of segment first.  */
  738. int  CHECK(orient,first,second) short orient; 
  739. int  first, second;
  740.     int   limit, bound;        /* maximum number of jumps */
  741.     int   small;            /* smaller of limit and bound */
  742.     float  delta;            /* cutoff factor   */
  743.     float cut;            /* cutoff score */
  744.     register  int   i;        /* index variable */
  745.     int  t, q;            /* temporary variables */
  746.     int  JUMP();
  747.     int  RJUMP();
  748.     int  JUMPC();
  749.     int  RJUMPC();
  750.  
  751.     delta = DELTA;
  752.     if ( orient )
  753.         limit = JUMP(CC, first, second, 1);
  754.     else
  755.         limit = JUMPC(CC, first, second);
  756.     bound = RJUMP(DD, second, first, orient);
  757.     small = limit <= bound ? limit : bound;
  758.     cut = 0;
  759.     for ( i = 1; i <= small; i++ )
  760.     { 
  761.         if ( (t = DD[i] - 1) >= over_len && t >= cut
  762.             && (q = CC[i] - 1) >= over_len && q >= cut )
  763.             return (1);
  764.         cut += delta;
  765.     }
  766.     if (DD[bound] >= delta*(bound-1) || CC[limit] >= delta*(limit-1))
  767.         return (1);
  768.     limit = JUMP(CC, second, first, orient);
  769.     if ( orient )
  770.         bound = RJUMP(DD, first, second, 1);
  771.     else
  772.         bound = RJUMPC(DD, first, second);
  773.     small = limit <= bound ? limit : bound;
  774.     cut = 0;
  775.     for ( i = 1; i <= small; i++ )
  776.     { 
  777.         if ( (t = DD[i] - 1) >= over_len && t >= cut
  778.             && (q = CC[i] - 1) >= over_len && q >= cut )
  779.             return (1);
  780.         cut += delta;
  781.     }
  782.     return (0);
  783. }
  784.  
  785. /* Compute a vector of lengths of jumps */
  786. int  JUMP(H,one,two,orient) int  H[], one, two; 
  787. short orient;
  788.     char *A, *B;            /* pointers to two sequences */
  789.     int  M, N;            /* lengths of two sequences */
  790.     int  *table;            /* pointer to a lookup table */
  791.     int  *loc;            /* pointer to a location table */
  792.     int  value;            /* value of a word */
  793.     int  maxd;            /* maximum length of an identical diagonal */
  794.     int  d;            /* length of current identical diagonal */
  795.     int  s;            /* length of jumps */
  796.     int  k;            /* number of jumps */
  797.  
  798.     register int  i, j, p;    /* index variables */
  799.  
  800.     A = segment[one].seq;
  801.     M = segment[one].length;
  802.     table = segment[one].lookup;
  803.     loc = segment[one].pos;
  804.     B = orient ? segment[two].seq : segment[two].rev;
  805.     N = segment[two].length;
  806.     for ( s = 1, k = 1; s <= N ; k++ )
  807.     { 
  808.         maxd = 0;
  809.         for ( value = -1, d = 0, j = s; d <= tuple && j <= N; j++, d++)
  810.         { 
  811.             if ( vert[B[j]] == 4 ) break;
  812.             value = 4 * (value + 1) + vert[B[j]];
  813.             if ( ! table[value] ) break;
  814.         }
  815.         if ( d > tuple )
  816.         { 
  817.             for ( p = table[value]; p ; p = loc[p] )
  818.             { 
  819.                 d = tuple + 1;
  820.                 for ( i = p+d, j = s+d; i <= M && j <= N; i++, j++, d++ )
  821.                     if ( A[i] != B[j] && vert[A[i]] != 4 && vert[B[j]] != 4 ) break;
  822.                 if ( maxd < d )
  823.                     maxd = d;
  824.                 if ( j > N ) break;
  825.             }
  826.         }
  827.         else 
  828.             maxd = d;
  829.         s += maxd + 1;
  830.         H[k] = s;
  831.     }
  832.     return (k - 1);
  833. }
  834.  
  835. /* Compute a vector of lengths of jumps for reverse complement of one */
  836. int  JUMPC(H,one,two) int  H[], one, two;
  837.     char *A, *B;            /* pointers to two sequences */
  838.     int  M, N;            /* lengths of two sequences */
  839.     int  *table;            /* pointer to a lookup table */
  840.     int  *loc;        /* pointer to a location table */
  841.     int  value;            /* value of a word */
  842.     int  maxd;            /* maximum length of an identical diagonal */
  843.     int  d;            /* length of current identical diagonal */
  844.     int  s;            /* length of jumps */
  845.     int  k;            /* number of jumps */
  846.  
  847.     register  int   i, j, p;    /* index variables */
  848.  
  849.     A = segment[one].rev;
  850.     M = segment[one].length;
  851.     table = segment[one].lookup;
  852.     loc = segment[one].pos;
  853.     B = segment[two].seq;
  854.     N = segment[two].length;
  855.     for ( s = 1, k = 1; s <= N ; k++ )
  856.     { 
  857.         maxd = 0;
  858.         for ( value = 0, d = 0, j = s; d <= tuple && j <= N; j++, d++)
  859.         { 
  860.             if ( vert[B[j]] == 4 ) break;
  861.             value += vertc[B[j]] * power[d];
  862.             if ( ! table[value+base[d]] ) break;
  863.         }
  864.         if ( d > tuple )
  865.         { 
  866.             for ( p = table[value+base[tuple]]; p ; p = loc[p] )
  867.             { 
  868.                 d = tuple + 1;
  869.                 for ( i = M+2-p, j = s+d; i <= M && j <= N; i++, j++, d++ )
  870.                     if ( A[i] != B[j] && vert[A[i]] != 4 && vert[B[j]] != 4 ) break;
  871.                 if ( maxd < d )
  872.                     maxd = d;
  873.                 if ( j > N ) break;
  874.             }
  875.         }
  876.         else 
  877.             maxd = d;
  878.         s += maxd + 1;
  879.         H[k] = s;
  880.     }
  881.     return (k - 1);
  882. }
  883.  
  884. /* Compute a vector of lengths of reverse jumps */
  885. int  RJUMP(H,one,two,orient) int  H[], one, two; 
  886. short orient;
  887.     char *A, *B;            /* pointers to two sequences */
  888.     int  N;            /* length of a sequence */
  889.     int  *table;            /* pointer to a lookup table */
  890.     int  *loc;        /* pointer to a location table */
  891.     int  value;            /* value of a word */
  892.     int  maxd;            /* maximum length of an identical diagonal */
  893.     int  d;            /* length of current identical diagonal */
  894.     int  s;            /* length of jumps */
  895.     int  k;            /* number of jumps */
  896.  
  897.     register  int   i, j, p;    /* index variables */
  898.  
  899.     A = segment[one].seq;
  900.     table = segment[one].lookup;
  901.     loc = segment[one].pos;
  902.     B = orient ? segment[two].seq : segment[two].rev;
  903.     N = segment[two].length;
  904.     for ( s = 1, k = 1; s <= N ; k++ )
  905.     { 
  906.         maxd = 0;
  907.         for (value = 0, d = 0, j = N+1-s; d <= tuple && j >= 1; j--, d++)
  908.         { 
  909.             if ( vert[B[j]] == 4 ) break;
  910.             value += vert[B[j]] * power[d];
  911.             if ( ! table[value+base[d]] ) break;
  912.         }
  913.         if ( d > tuple )
  914.         { 
  915.             for ( p = table[value+base[tuple]]; p ; p = loc[p] )
  916.             { 
  917.                 d = tuple + 1;
  918.                 for ( i = p-1, j = N+1-s-d; i >= 1 && j >= 1; i--, j--, d++ )
  919.                     if ( A[i] != B[j] && vert[A[i]] != 4 && vert[B[j]] != 4 ) break;
  920.                 if ( maxd < d )
  921.                     maxd = d;
  922.                 if ( j < 1 ) break;
  923.             }
  924.         }
  925.         else 
  926.             maxd = d;
  927.         s += maxd + 1;
  928.         H[k] = s;
  929.     }
  930.     return (k - 1);
  931. }
  932.  
  933. /* Compute a vector of lengths of reverse jumps for reverse complement */
  934. int  RJUMPC(H,one,two) int  H[], one, two;
  935.     char *A, *B;            /* pointers to two sequences */
  936.     int  M, N;            /* lengths of two sequences */
  937.     int  *table;            /* pointer to a lookup table */
  938.     int  *loc;        /* pointer to a location table */
  939.     int  value;            /* value of a word */
  940.     int  maxd;            /* maximum length of an identical diagonal */
  941.     int  d;            /* length of current identical diagonal */
  942.     int  s;            /* length of jumps */
  943.     int  k;            /* number of jumps */
  944.  
  945.     register  int   i, j, p;    /* index variables */
  946.  
  947.     A = segment[one].rev;
  948.     M = segment[one].length;
  949.     table = segment[one].lookup;
  950.     loc = segment[one].pos;
  951.     B = segment[two].seq;
  952.     N = segment[two].length;
  953.     for ( s = 1, k = 1; s <= N ; k++ )
  954.     { 
  955.         maxd = 0;
  956.         for (value = -1, d = 0, j = N+1-s; d <= tuple && j >= 1; j--, d++)
  957.         { 
  958.             if ( vert[B[j]] == 4 ) break;
  959.             value = 4 * (value + 1) + vertc[B[j]];
  960.             if ( ! table[value] ) break;
  961.         }
  962.         if ( d > tuple )
  963.         { 
  964.             for ( p = table[value]; p ; p = loc[p] )
  965.             { 
  966.                 d = tuple + 1;
  967.                 i = M - p - tuple;
  968.                 for ( j = N-s-tuple; i >= 1 && j >= 1; i--, j--, d++ )
  969.                     if ( A[i] != B[j] && vert[A[i]] != 4 && vert[B[j]] != 4 ) break;
  970.                 if ( maxd < d )
  971.                     maxd = d;
  972.                 if ( j < 1 ) break;
  973.             }
  974.         }
  975.         else 
  976.             maxd = d;
  977.         s += maxd + 1;
  978.         H[k] = s;
  979.     }
  980.     return (k - 1);
  981. }
  982.  
  983. /* Construct contigs */
  984. ASSEM()
  985.     char *ckalloc();        /* space-allocating function */
  986.     register  int   i, j, k;    /* index variables */
  987.     overptr  node1, x, y;        /* temporary pointer */
  988.     int   five, three;        /* indices of 5' and 3' segments */
  989.     short   orienti;        /* orientation of 5' segment */
  990.     short   orientj;        /* orientation of 3' segment */
  991.     short   sorted;        /* boolean variable */
  992.  
  993.     contigs = ( struct CONS * ) ckalloc( seg_num * sizeof(struct CONS));
  994.     for ( i = 0; i < seg_num; i++ )
  995.     { 
  996.         contigs[i].isfive[0] = contigs[i].isthree[0] = 1;
  997.         contigs[i].isfive[1] = contigs[i].isthree[1] = 1;
  998.         contigs[i].other = i;
  999.         contigs[i].group = contigs[i].child = -1;
  1000.         contigs[i].brother = contigs[i].father = -1;
  1001.     }
  1002.     for ( i = 0; i < seg_num; i++ )
  1003.         if ( ! segment[i].kind )
  1004.             for ( ; ; )
  1005.             { 
  1006.                 for ( y = segment[i].list; y->kind; y = y->next )
  1007.                     ;
  1008.                 for ( x = y->next; x != 0; x = x->next )
  1009.                     if ( ! x->kind && x->score > y->score )
  1010.                         y = x;
  1011.                 for ( j = y->number; (k = contigs[j].father) != -1; j = k )
  1012.                     ;
  1013.                 if ( j != i )
  1014.                 { 
  1015.                     contigs[i].father = j = y->number;
  1016.                     contigs[i].brother = contigs[j].child;
  1017.                     contigs[j].child = i;
  1018.                     contigs[i].node[1] = y;
  1019.                     break;
  1020.                 }
  1021.                 else
  1022.                 { 
  1023.                     if ( segment[i].list->number == y->number )
  1024.                         segment[i].list = y->next;
  1025.                     else
  1026.                     { 
  1027.                         for ( x = segment[i].list; x->next->number != y->number ; )
  1028.                             x = x->next;
  1029.                         x->next = y->next;
  1030.                     }
  1031.                     for ( x = segment[i].list; x != 0 && x->kind; x = x->next )
  1032.                         ;
  1033.                     if ( x == 0 )
  1034.                     { 
  1035.                         segment[i].kind = 1;
  1036.                         break;
  1037.                     }
  1038.                 }
  1039.             }
  1040.     edge = ( overptr * ) ckalloc( edge_num * sizeof(overptr) );
  1041.     for ( j = 0, i = 0; i < seg_num; i++ )
  1042.         if ( segment[i].kind )
  1043.             for ( node1 = segment[i].list; node1 != 0; node1 = node1->next )
  1044.                 if ( segment[node1->number].kind )
  1045.                     edge[j++] = node1;
  1046.     edge_num = j;
  1047.     for ( i = edge_num - 1; i > 0; i-- )
  1048.     { 
  1049.         sorted = 1;
  1050.         for ( j = 0; j < i; j++ )
  1051.             if ( edge[j]->score < edge[j+1]->score )
  1052.             { 
  1053.                 node1 = edge[j];
  1054.                 edge[j] = edge[j+1];
  1055.                 edge[j+1] = node1;
  1056.                 sorted = 0;
  1057.             }
  1058.         if ( sorted )
  1059.             break;
  1060.     }
  1061.     for ( k = 0; k < edge_num; k++ )
  1062.     { 
  1063.         five = edge[k]->host;
  1064.         three = edge[k]->number;
  1065.         orienti = edge[k]->orienti;
  1066.         orientj = edge[k]->orientj;
  1067.         if ( contigs[five].isthree[orienti] &&
  1068.             contigs[three].isfive[orientj] && contigs[five].other != three )
  1069.         { 
  1070.             contigs[five].isthree[orienti] = 0;
  1071.             contigs[three].isfive[orientj] = 0;
  1072.             contigs[five].next[orienti] = three;
  1073.             contigs[five].orient[orienti] = orientj;
  1074.             contigs[five].node[orienti] = edge[k];
  1075.             contigs[three].isthree[(j = 1 - orientj)] = 0;
  1076.             contigs[five].isfive[(i = 1 - orienti)] = 0;
  1077.             contigs[three].next[j] = five;
  1078.             contigs[three].orient[j] = i;
  1079.             contigs[three].node[j] = edge[k];
  1080.             i = contigs[three].other;
  1081.             j = contigs[five].other;
  1082.             contigs[i].other = j;
  1083.             contigs[j].other = i;
  1084.         }
  1085.     }
  1086. }
  1087.  
  1088. REPAIR()
  1089.     int  endi, endj, stari, starj;    /* endpoint and startpoint */
  1090.  
  1091.     short orienti, orientj;        /* orientation of segments */
  1092.     short isconi, isconj;            /* containment condition   */
  1093.     int   score;               /* the max score */
  1094.     int   i, j, f, d, e;            /* row and column indices  */
  1095.     char *ckalloc();            /* space-allocating function */
  1096.     char *A, *B;
  1097.     int  M, N;
  1098.     overptr node1;
  1099.     int   piece_num;                   /* The number of pieces */
  1100.     int   count, limit;
  1101.     int   number;
  1102.     int   hit;
  1103.  
  1104.     piece = ( struct VX * ) ckalloc( seg_num * sizeof(struct VX));
  1105.     for ( j = 0, i = 0; i < seg_num; i++ )
  1106.         if (segment[i].kind && (contigs[i].isfive[1] || contigs[i].isfive[0]))
  1107.             piece[j++].id = i;
  1108.     piece_num = j;
  1109.     for ( i = 0; i < piece_num; i++ )
  1110.     { 
  1111.         piece[i].kind = 1;
  1112.         piece[i].list = 0;
  1113.     }
  1114.     limit = 2 * ( piece_num - 1 );
  1115.     hit = number = 0;
  1116.     for ( orienti = 0, d = 0; d < limit ; d++ )
  1117.     { 
  1118.         i = piece[(e = d / 2)].id;
  1119.         orienti = 1 - orienti;
  1120.         A = orienti ? segment[i].seq : segment[i].rev;
  1121.         M = segment[i].length;
  1122.         for ( f = e+1; f < piece_num ; f++ )
  1123.         { 
  1124.             j = piece[f].id;
  1125.             B = segment[j].seq;
  1126.             orientj = 1;
  1127.             N = segment[j].length;
  1128.             SCORE = 0;
  1129.             hit++;
  1130.             big_pass(A,B,M,N,orienti,orientj);
  1131.             if ( SCORE > CUTOFF )
  1132.             { 
  1133.                 score = SCORE;
  1134.                 stari = ++STARI;
  1135.                 starj = ++STARJ;
  1136.                 endi = ENDI;
  1137.                 endj = ENDJ;
  1138.                 isconi = stari == 1 && endi == M;
  1139.                 isconj = starj == 1 && endj == N;
  1140.                 node1 = ( overptr ) ckalloc( (int ) sizeof(over));
  1141.                 if ( isconi || isconj )
  1142.                     node1->kind = 0;        /* containment */
  1143.                 else
  1144.                 { 
  1145.                     node1->kind = 1; 
  1146.                     number++; 
  1147.                 }    /* overlap */
  1148.                 if ( endi == M && ! isconj )     /*i is 5'*/
  1149.                 { 
  1150.                     node1->number = j;
  1151.                     node1->host = i;
  1152.                     node1->ind = f;
  1153.                     node1->stari = stari;
  1154.                     node1->endi = endi;
  1155.                     node1->orienti = orienti;
  1156.                     node1->starj = starj;
  1157.                     node1->endj = endj;
  1158.                     node1->orientj = orientj;
  1159.                 }
  1160.                 else    /* j is 5' */
  1161.                 { 
  1162.                     node1->number = i;
  1163.                     node1->host = j;
  1164.                     node1->ind = e;
  1165.                     node1->stari = starj;
  1166.                     node1->endi = endj;
  1167.                     node1->orienti = orientj;
  1168.                     node1->starj = stari;
  1169.                     node1->endj = endi;
  1170.                     node1->orientj = orienti;
  1171.                 }
  1172.                 node1->score = score;
  1173.                 count = node1->number == i ? f : e;
  1174.                 node1->next = piece[count].list;
  1175.                 piece[count].list = node1;
  1176.                 if ( ! node1->kind )
  1177.                     piece[count].kind = 0;
  1178.             }
  1179.         }
  1180.     }
  1181.     REASSEM(piece_num, number);
  1182. }
  1183.  
  1184. /* Construct contigs */
  1185. REASSEM(piece_num, number) int  piece_num, number;
  1186.     char *ckalloc();        /* space-allocating function */
  1187.     int   i, j, k, d;        /* index variables */
  1188.     overptr  node1, x, y;        /* temporary pointer */
  1189.     int   five, three;        /* indices of 5' and 3' segments */
  1190.     short   orienti;        /* orientation of 5' segment */
  1191.     short   orientj;        /* orientation of 3' segment */
  1192.     short   sorted;        /* boolean variable */
  1193.  
  1194.     for ( d = 0; d < piece_num; d++ )
  1195.         if ( ! piece[d].kind )
  1196.             for ( i = piece[d].id ; ; )
  1197.             { 
  1198.                 for ( y = piece[d].list; y->kind; y = y->next )
  1199.                     ;
  1200.                 for ( x = y->next; x != 0; x = x->next )
  1201.                     if ( ! x->kind && x->score > y->score )
  1202.                         y = x;
  1203.                 for ( j = y->number; (k = contigs[j].father) != -1; j = k )
  1204.                     ;
  1205.                 if ( j != i && RECONCILE(y,&piece_num,&number) )
  1206.                 { 
  1207.                     contigs[i].father = j = y->number;
  1208.                     contigs[i].brother = contigs[j].child;
  1209.                     contigs[j].child = i;
  1210.                     contigs[i].node[1] = y;
  1211.                     segment[i].kind = 0;
  1212.                     break;
  1213.                 }
  1214.                 else
  1215.                 { 
  1216.                     if ( piece[d].list->number == y->number )
  1217.                         piece[d].list = y->next;
  1218.                     else
  1219.                     { 
  1220.                         for ( x = piece[d].list; x->next->number != y->number ; )
  1221.                             x = x->next;
  1222.                         x->next = y->next;
  1223.                     }
  1224.                     for ( x = piece[d].list; x != 0 && x->kind; x = x->next )
  1225.                         ;
  1226.                     if ( x == 0 )
  1227.                     { 
  1228.                         piece[d].kind = 1;
  1229.                         break;
  1230.                     }
  1231.                 }
  1232.             }
  1233.     if ( number > edge_num )
  1234.         edge = ( overptr * ) ckalloc( number * sizeof(overptr) );
  1235.     for ( j = 0, d = 0; d < piece_num; d++ )
  1236.         if ( piece[d].kind )
  1237.             for ( node1 = piece[d].list; node1 != 0; node1 = node1->next )
  1238.                 if ( piece[node1->ind].kind )
  1239.                     edge[j++] = node1;
  1240.     edge_num = j;
  1241.     for ( i = edge_num - 1; i > 0; i-- )
  1242.     { 
  1243.         sorted = 1;
  1244.         for ( j = 0; j < i; j++ )
  1245.             if ( edge[j]->score < edge[j+1]->score )
  1246.             { 
  1247.                 node1 = edge[j];
  1248.                 edge[j] = edge[j+1];
  1249.                 edge[j+1] = node1;
  1250.                 sorted = 0;
  1251.             }
  1252.         if ( sorted )
  1253.             break;
  1254.     }
  1255.     for ( k = 0; k < edge_num; k++ )
  1256.     { 
  1257.         five = edge[k]->host;
  1258.         three = edge[k]->number;
  1259.         orienti = edge[k]->orienti;
  1260.         orientj = edge[k]->orientj;
  1261.         if ( contigs[five].isthree[orienti] &&
  1262.             contigs[three].isfive[orientj] && contigs[five].other != three )
  1263.         { 
  1264.             contigs[five].isthree[orienti] = 0;
  1265.             contigs[three].isfive[orientj] = 0;
  1266.             contigs[five].next[orienti] = three;
  1267.             contigs[five].orient[orienti] = orientj;
  1268.             contigs[five].node[orienti] = edge[k];
  1269.             contigs[three].isthree[(j = 1 - orientj)] = 0;
  1270.             contigs[five].isfive[(i = 1 - orienti)] = 0;
  1271.             contigs[three].next[j] = five;
  1272.             contigs[three].orient[j] = i;
  1273.             contigs[three].node[j] = edge[k];
  1274.             i = contigs[three].other;
  1275.             j = contigs[five].other;
  1276.             contigs[i].other = j;
  1277.             contigs[j].other = i;
  1278.         }
  1279.     }
  1280. }
  1281.  
  1282. RECONCILE(y, pp,nn) overptr y; 
  1283. int  *pp,*nn;
  1284.     short orienti, orientj;        /* orientation of segments */
  1285.     short orientk, orientd;        /* orientation of segments */
  1286.     int   i, j, k, d, f;            /* row and column indices  */
  1287.     char *ckalloc();            /* space-allocating function */
  1288.     char *A, *B;
  1289.     int  M, N;
  1290.     overptr node1;
  1291.  
  1292.     k = y->host;
  1293.     d = y->number;
  1294.     orientk = y->orienti;
  1295.     orientd = y->orientj;
  1296.     if ( ! contigs[k].isthree[orientk] )
  1297.     { 
  1298.         if ( ! piece[y->ind].kind ) return (0);
  1299.         if ( contigs[d].isthree[orientd] )
  1300.         { 
  1301.             orienti = orientd;
  1302.             i = d;
  1303.             orientj = contigs[k].orient[orientk];
  1304.             j = contigs[k].next[orientk];
  1305.         }
  1306.         else
  1307.             return (0);
  1308.     }
  1309.     else
  1310.         if ( ! contigs[k].isfive[orientk] )
  1311.         { 
  1312.             if ( ! piece[y->ind].kind ) return (0);
  1313.             if ( contigs[d].isfive[orientd] )
  1314.             { 
  1315.                 orienti = contigs[k].orient[1-orientk];
  1316.                 orienti = 1 - orienti;
  1317.                 i = contigs[k].next[1-orientk];
  1318.                 orientj = orientd;
  1319.                 j = d;
  1320.             }
  1321.             else
  1322.                 return (0);
  1323.         }
  1324.         else
  1325.             return (0);
  1326.     A = orienti ? segment[i].seq : segment[i].rev;
  1327.     M = segment[i].length;
  1328.     B = orientj ? segment[j].seq : segment[j].rev;
  1329.     N = segment[j].length;
  1330.     SCORE = 0;
  1331.     big_pass(A,B,M,N,orienti,orientj);
  1332.     if ( SCORE > CUTOFF && ENDI - STARI > over_len && ENDI == M && STARJ == 0 )
  1333.     { 
  1334.         node1 = ( overptr ) ckalloc( (int ) sizeof(over));
  1335.         node1->kind = 1;
  1336.         node1->host = i;
  1337.         node1->number = j;
  1338.         node1->stari = ++STARI;
  1339.         node1->endi = ENDI;
  1340.         node1->orienti = orienti;
  1341.         node1->starj = ++STARJ;
  1342.         node1->endj = ENDJ;
  1343.         node1->orientj = orientj;
  1344.         node1->score = SCORE;
  1345.         piece[*pp].kind = 1;
  1346.         if ( i == d )
  1347.         { 
  1348.             node1->ind = *pp;
  1349.             node1->next = piece[y->ind].list;
  1350.             piece[y->ind].list = node1;
  1351.             piece[*pp].id = j;
  1352.             piece[*pp].list = 0;
  1353.         }
  1354.         else
  1355.         { 
  1356.             node1->ind = y->ind;
  1357.             piece[*pp].list = node1;
  1358.             node1->next = 0;
  1359.             piece[*pp].id = i;
  1360.         }
  1361.         (*nn)++;
  1362.         (*pp)++;
  1363.         f = contigs[k].other;
  1364.         if ( ! contigs[k].isthree[orientk] )
  1365.         { 
  1366.             contigs[j].isfive[orientj] = 1;
  1367.             contigs[j].isthree[1 - orientj] = 1;
  1368.             contigs[k].isthree[orientk] = 1;
  1369.             contigs[k].isfive[1 - orientk] = 1;
  1370.             contigs[f].other = j;
  1371.             contigs[j].other = f;
  1372.         }
  1373.         else
  1374.         { 
  1375.             contigs[i].isthree[orienti] = 1;
  1376.             contigs[i].isfive[1 - orienti] = 1;
  1377.             contigs[k].isfive[orientk] = 1;
  1378.             contigs[k].isthree[1 - orientk] = 1;
  1379.             contigs[f].other = i;
  1380.             contigs[i].other = f;
  1381.         }
  1382.         contigs[k].other = k;
  1383.         return (1);
  1384.     }
  1385.     return (0);
  1386. }
  1387.  
  1388. /* Construct a tree of overlapping-containment segments */
  1389. FORM_TREE()
  1390.     register  int   i, j, k;    /* index variables */
  1391.     char *ckalloc();        /* space-allocating function */
  1392.     overptr  node1;        /* temporary pointer */
  1393.     short   orient;        /* orientation of segment */
  1394.     int   group;            /* serial number of contigs  */
  1395.     char *A, *B;            /* pointers to segment sequences */
  1396.     int  stari, endi, starj, endj;/* positions where alignment begins */
  1397.     int  M, N;            /* lengths of segment sequences */
  1398.     int   count;            /* temporary variables */
  1399.  
  1400.     mtree = ( struct TTREE * ) ckalloc( seg_num * sizeof(struct TTREE));
  1401.     for ( i = 0; i < seg_num; i++ )
  1402.     { 
  1403.         mtree[i].head = 0;
  1404.         mtree[i].next = mtree[i].child = mtree[i].brother = -1;
  1405.     }
  1406.     for ( group = 0, i = 0; i < seg_num; i++ )
  1407.         if ( segment[i].kind && contigs[i].group < 0 &&
  1408.             ( contigs[i].isfive[1] || contigs[i].isfive[0] ) )
  1409.         { 
  1410.             orient = contigs[i].isfive[1] ? 1 : 0;
  1411.             mtree[i].head = 1;
  1412.             for ( j = i; ;  )
  1413.             { 
  1414.                 contigs[j].group = group;
  1415.                 mtree[j].orient = orient;
  1416.                 SORT(j, orient);
  1417.                 if ( contigs[j].isthree[orient] )
  1418.                     break;
  1419.                 else
  1420.                 { 
  1421.                     k = contigs[j].next[orient];
  1422.                     node1 = contigs[j].node[orient];
  1423.                     if ( j == node1->host )
  1424.                     { 
  1425.                         stari = node1->stari;
  1426.                         endi  = node1->endi;
  1427.                         starj = node1->starj;
  1428.                         endj  = node1->endj;
  1429.                         A = node1->orienti ? segment[j].seq : segment[j].rev;
  1430.                         B = node1->orientj ? segment[k].seq : segment[k].rev;
  1431.                     }
  1432.                     else
  1433.                     { 
  1434.                         M = segment[j].length;
  1435.                         stari = M + 1 - node1->endj;
  1436.                         endi = M + 1 - node1->starj;
  1437.                         N = segment[k].length;
  1438.                         starj = N + 1 - node1->endi;
  1439.                         endj = N + 1 - node1->stari;
  1440.                         A = node1->orientj ? segment[j].rev : segment[j].seq;
  1441.                         B = node1->orienti ? segment[k].rev : segment[k].seq;
  1442.                     }
  1443.                     M = endi - stari + 1;
  1444.                     N = endj - starj + 1;
  1445.                     sapp = S;
  1446.                     last = 0;
  1447.                     al_len = no_mat = no_mis = 0;
  1448.                     (void) diff(&A[stari]-1, &B[starj]-1,M,N,q,q);
  1449.                     count = ( (N = sapp - S) + 1 ) * sizeof(int );
  1450.                     mtree[k].script = ( int  * ) ckalloc( count );
  1451.                     for ( M = 0; M < N; M++)
  1452.                         mtree[k].script[M] = S[M];
  1453.                     mtree[k].size = N;
  1454.                     mtree[k].begin = stari;
  1455.                     mtree[j].next = k;
  1456.                     orient = contigs[j].orient[orient];
  1457.                     j = k;
  1458.                 }
  1459.             }
  1460.             group++;
  1461.         }
  1462. }
  1463.  
  1464. /* Sort the children of each node by the `begin' field */
  1465. SORT(seg, ort) int  seg; 
  1466. short ort;
  1467.     register  int   i, j, k;    /* index variables */
  1468.     char *ckalloc();        /* space-allocating function */
  1469.     overptr  node1;        /* temporary pointer */
  1470.     short   orient;        /* orientation of segment */
  1471.     char *A, *B;            /* pointers to segment sequences */
  1472.     int  stari, endi, starj, endj;/* positions where alignment begins */
  1473.     int  M, N;            /* lengths of segment sequences */
  1474.     int   count;            /* temporary variables */
  1475.  
  1476.     for ( j = contigs[seg].child; j != -1; j = contigs[j].brother )
  1477.     { 
  1478.         node1 = contigs[j].node[1];
  1479.         if ( ort == node1->orientj )
  1480.         { 
  1481.             stari = node1->starj;
  1482.             endi  = node1->endj;
  1483.             starj = node1->stari;
  1484.             endj  = node1->endi;
  1485.             A = node1->orientj ? segment[seg].seq : segment[seg].rev;
  1486.             B = node1->orienti ? segment[j].seq : segment[j].rev;
  1487.             orient = node1->orienti;
  1488.         }
  1489.         else
  1490.         { 
  1491.             M = segment[seg].length;
  1492.             stari = M + 1 - node1->endj;
  1493.             endi = M + 1 - node1->starj;
  1494.             N = segment[j].length;
  1495.             starj = N + 1 - node1->endi;
  1496.             endj = N + 1 - node1->stari;
  1497.             A = node1->orientj ? segment[seg].rev : segment[seg].seq;
  1498.             B = node1->orienti ? segment[j].rev : segment[j].seq;
  1499.             orient = 1 -  node1->orienti;
  1500.         }
  1501.         M = endi - stari + 1;
  1502.         N = endj - starj + 1;
  1503.         sapp = S;
  1504.         last = 0;
  1505.         al_len = no_mat = no_mis = 0;
  1506.         (void) diff(&A[stari]-1, &B[starj]-1,M,N,q,q);
  1507.         count = ( (M = sapp - S ) + 1 ) * sizeof(int );
  1508.         mtree[j].script = ( int  * ) ckalloc( count );
  1509.         for ( k = 0; k < M; k++)
  1510.             mtree[j].script[k] = S[k];
  1511.         mtree[j].size = M;
  1512.         mtree[j].begin = stari;
  1513.         mtree[j].orient = orient;
  1514.         if ( mtree[seg].child == -1 )
  1515.             mtree[seg].child = j;
  1516.         else
  1517.         { 
  1518.             i = mtree[seg].child;
  1519.             if ( mtree[i].begin >= stari )
  1520.             { 
  1521.                 mtree[j].brother = i;
  1522.                 mtree[seg].child = j;
  1523.             }
  1524.             else
  1525.             { 
  1526.                 M = mtree[i].brother;
  1527.                 for ( ; M != -1; i = M, M = mtree[M].brother )
  1528.                     if ( mtree[M].begin >= stari ) break;
  1529.                 mtree[j].brother = M;
  1530.                 mtree[i].brother = j;
  1531.             }
  1532.         }
  1533.         SORT(j, orient);
  1534.     }
  1535. }
  1536.  
  1537.  
  1538. /* Display the alignments of segments */
  1539. SHOW()
  1540.     register  int   i, j, k;    /* index variables */
  1541.     char *ckalloc();        /* space-allocating function */
  1542.     int   n;            /* number of working segments */
  1543.     int   limit;            /* number of slots in work */
  1544.     int   col;            /* number of output columns prepared */
  1545.     short done;            /* tells if current group is done */
  1546.     rowptr root;            /* pointer to root of op tree */
  1547.     int   sym[6];            /* occurrance counts for six chars */
  1548.     char  c;            /* temp variable */
  1549.     rowptr t, w, yy;        /* temp pointer */
  1550.     int    x;            /* temp variables */
  1551.     int   group;            /* Contigs number */
  1552.     char  conlit[20], *a;        /* String form of contig number */
  1553.     char  *spt;            /* pointer to the start of consensus */
  1554.  
  1555.     work = ( rowptr * ) ckalloc( seg_num * sizeof(rowptr));
  1556.     group = 0;
  1557.     yy = 0;
  1558.     for ( j = 0; j < 6; j++ )
  1559.         sym[j] = 0;
  1560.     n = limit = col = 0;
  1561.     for ( i = 0; i < seg_num; i++ )
  1562.         if ( mtree[i].head )
  1563.         { 
  1564.             (void) sprintf(conlit, "\n>Contig-%d\n", group);
  1565.             for ( a = conlit; *a; )
  1566.                 *allconpt++ = *a++;
  1567.             /* Mod by S.S.
  1568.      (void) printf("\n#Contig %d\n\n", group++);
  1569. */
  1570.             group++;
  1571.             done = 0;
  1572.             ENTER(&limit, &n, i, col, yy);
  1573.             root = work[0];
  1574.             spt = allconpt;
  1575.             while ( ! done )
  1576.             { 
  1577.                 for ( j = 0; j < n; j++ )    /* get segments into work */
  1578.                 { 
  1579.                     t = work[j];
  1580.                     k = t->id;
  1581.                     if ((x = mtree[k].next) != -1 && mtree[x].begin == t->loc)
  1582.                     { 
  1583.                         ENTER(&limit, &n, x, col, t);
  1584.                         mtree[k].next = -1;
  1585.                     }
  1586.                     for ( x = mtree[k].child; x != -1; x = mtree[x].brother )
  1587.                         if ( mtree[x].begin == t->loc )
  1588.                         { 
  1589.                             ENTER(&limit, &n, x, col, t);
  1590.                             mtree[k].child = mtree[x].brother;
  1591.                         }
  1592.                         else
  1593.                             break;
  1594.                 }
  1595.                 COLUMN(root);        /* determine next column */
  1596.                 root->c = root->kind;
  1597.                 for ( t = head; t != 0; t = t->link )
  1598.                     t->c = t->kind;
  1599.                 for ( j = 0; j < n; j++ )
  1600.                 { 
  1601.                     t = work[j];
  1602.                     if ( t->done )
  1603.                         *t->a++ = ' ';
  1604.                     else
  1605.                     { 
  1606.                         if ( t->c == 'L' )
  1607.                         { 
  1608.                             if ( t->loc == 1 )
  1609.                                 t->offset = allconpt - spt;
  1610.                             c = *t->a++ = t->seq[t->loc++];
  1611.                         }
  1612.                         else
  1613.                             if ( t->loc > 1 )
  1614.                                 c = *t->a++ = '-';
  1615.                             else
  1616.                                 c = *t->a++ = ' ';
  1617.                         if ( c != ' ' )
  1618.                             if ( c == '-' )
  1619.                                 sym[5] += 1;
  1620.                             else
  1621.                                 sym[vert[c]] += 1;
  1622.                         t->c = ' ';
  1623.                     }
  1624.                 }
  1625.                 /* determine consensus char */
  1626.                 k = sym[0] + sym[1] + sym[2] + sym[3] + sym[4];
  1627.                 if ( k < sym[5] )
  1628.                     *allconpt++ = '-';
  1629.                 else
  1630.                     if ( sym[0] == sym[1] && sym[1] == sym[2] &&
  1631.                         sym[2] == sym[3] )
  1632.                         *allconpt++ = 'N';
  1633.                     else
  1634.                     { 
  1635.                         k = sym[0];
  1636.                         c = 'A';
  1637.                         if ( k < sym[1] ) { 
  1638.                             k = sym[1]; 
  1639.                             c = 'C'; 
  1640.                         }
  1641.                         if ( k < sym[2] ) { 
  1642.                             k = sym[2]; 
  1643.                             c = 'G'; 
  1644.                         }
  1645.                         if ( k < sym[3] ) c = 'T';
  1646.                         *allconpt++ = c;
  1647.                     }
  1648.                 for ( j = 0; j < 6; j++ )
  1649.                     sym[j] = 0;
  1650.                 for ( t = head; t != 0; t = t->link )
  1651.                 { 
  1652.                     NEXTOP(t);
  1653.                     if ( t->done )    /* delete it from op tree */
  1654.                     { 
  1655.                         w = t->father;
  1656.                         if ( w->child->id == t->id )
  1657.                             w->child = t->brother;
  1658.                         else
  1659.                         { 
  1660.                             w = w->child;
  1661.                             for ( ; w->brother->id != t->id; w = w->brother )
  1662.                                 ;
  1663.                             w->brother = t->brother;
  1664.                         }
  1665.                     }
  1666.                 }
  1667.                 if ( root->loc > root->length )    /* check root node */
  1668.                 { 
  1669.                     root->done = 1;
  1670.                     if ( (w = root->child) != 0 )
  1671.                     { 
  1672.                         w->father = 0;
  1673.                         root = w;
  1674.                     }
  1675.                     else
  1676.                         done = 1;
  1677.                 }
  1678.                 col++;
  1679.                 if ( col == LINELEN || done )    /* output */
  1680.                 { 
  1681.                     col = 0;
  1682.                     for ( j = 0; j < n; j++ )
  1683.                     { 
  1684.                         t = work[j];
  1685.                         if ( t->done )
  1686.  
  1687. /*
  1688.         Mod by S.S.
  1689.               { (void) printf("#");
  1690.             for ( a = t->name; *a; a++ )
  1691.               (void) printf("%c", *a);
  1692. */
  1693.  
  1694.             {  /* dgg output == fasta compatible */ 
  1695.             short ii, isrev;
  1696.             isrev= (t->name[strlen(t->name)] == '-');
  1697.             
  1698.             (void) fprintf(fout,">cap_");
  1699.             for ( a = t->name; *a; a++ ) (void) fprintf(fout,"%c", *a); 
  1700.             (void) fprintf(fout,"\n");
  1701.             
  1702.             /* need to print offset (.) and reverse as needed */    
  1703.             for ( ii = 0, k=0 ; ii < t->offset; ii++ ) {
  1704.                 k++;
  1705.                 (void) fprintf(fout,"%c", '.'); 
  1706.                 if ( k == LINELEN ) { 
  1707.                     (void)  fprintf(fout,"\n");
  1708.                     k = 0;
  1709.                     }            
  1710.                 }
  1711.         
  1712.             if (isrev) {
  1713.                 for ( a = t->a-1 ; a != t->line-1; a-- )
  1714.                     if ( *a != ' ' ) { 
  1715.                         k++;
  1716.                         (void) fprintf(fout,"%c", nuccomp(*a));
  1717.                         if ( k == LINELEN ) { 
  1718.                             (void)  fprintf(fout,"\n");
  1719.                             k = 0;
  1720.                             }            
  1721.                     }
  1722.                 }
  1723.             else {
  1724.                 for ( /*k = 0,*/ a = t->line ; a != t->a; a++ )
  1725.                     if ( *a != ' ' ) { 
  1726.                         k++;
  1727.                         (void)  fprintf(fout,"%c", *a);
  1728.                         if ( k == LINELEN ) { 
  1729.                             (void)  fprintf(fout,"\n");
  1730.                             k = 0;
  1731.                             }
  1732.                     }
  1733.                 }
  1734.             if (k) (void)  fprintf(fout,"\n");
  1735.             }
  1736.             
  1737. /***** s.s.                
  1738.                         {
  1739.                             int jj;
  1740.                             (void) printf("{\nname    ");
  1741.                             for(jj=0;jj<strlen(t->name)-1;jj++)
  1742.                                 (void) printf("%c", t->name[jj]);
  1743.                             printf("\nstrandedness    %c\n",
  1744.                                 t->name[strlen(t->name)] == '+'? '1':'2');
  1745.  
  1746.                             printf("offset    %d\ntype  DNA\ngroup-ID    %d\nsequence    \"\n",
  1747.                                 t->offset,group);
  1748.                             for ( k = 0, a = t->line ; a != t->a; a++ )
  1749.                                 if ( *a != ' ' )
  1750.                                 { 
  1751.                                     k++;
  1752.                                     (void)  printf("%c", *a);
  1753.                                     if ( k == LINELEN )
  1754.                                     { 
  1755.                                         (void)  printf("\n");
  1756.                                         k = 0;
  1757.                                     }
  1758.                                 }
  1759.  
  1760.                             (void)  printf("\"\n}\n");
  1761.                         }
  1762. ******/
  1763.                         if ( t->linesize - (t->a - t->line) < LINELEN + 3 )
  1764.                             ALOC_SEQ(t);
  1765.                     }
  1766.                     if ( !done )
  1767.                     { 
  1768.                         for ( k = j = n - 1; j >= 0; j-- )
  1769.                             if ( work[j]->done )
  1770.                             { 
  1771.                                 t = work[j];
  1772.                                 for ( x = j; x < k; x++ )
  1773.                                     work[x] = work[x+1];
  1774.                                 work[k--] = t;
  1775.                             }
  1776.                         n = k + 1;
  1777.                     }
  1778.                     else
  1779.                         n = 0;
  1780.                 }
  1781.             }
  1782.         }
  1783.  
  1784.     *allconpt = 0; /* dgg, term string */
  1785.   /* (void)    fprintf(fout,"\n>Consensus\n"); -- dgg added back */
  1786.     for ( a = allconsen, k=0 ; *a; a++ ) {
  1787.         k++;
  1788.         (void) fprintf(fout,"%c", *a); 
  1789.         if ( k == LINELEN ) { 
  1790.             (void) fprintf(fout,"\n");
  1791.             k = 0;
  1792.             }            
  1793.         }
  1794.     fprintf(fout,"\n\n");
  1795. }
  1796.  
  1797. /* allocate more space for output fragment */
  1798. ALOC_SEQ(t) rowptr t;
  1799.     char  *start, *end, *p;
  1800.     t->linesize *= 2;
  1801.     start = t->line;
  1802.     end = t->a;
  1803.     t->line = ( char * ) ckalloc( t->linesize * sizeof(char));
  1804.     for ( t->a = t->line, p  = start ; p != end; )
  1805.         *t->a++ = *p++;
  1806.     free(start);
  1807. }
  1808.  
  1809. /* enter a segment into working set */
  1810. ENTER(b, d, id, pos, par) int  *b, *d, id, pos; 
  1811. rowptr par;
  1812.     int  i;
  1813.     char *ckalloc();        /* space-allocating function */
  1814.     rowptr  t;
  1815.  
  1816.     if ( *b <= *d )
  1817.     { 
  1818.         work[*b] = ( rowptr ) ckalloc( (int ) sizeof(row));
  1819.         work[*b]->line = ( char * ) ckalloc( SEQLEN * sizeof(char));
  1820.         work[*b]->linesize = SEQLEN;
  1821.         *b += 1;
  1822.     }
  1823.     t = work[*d];
  1824.     *d += 1;
  1825.     t->a = t->line;
  1826.     for ( i = 0; i < pos; i++ )
  1827.         *t->a++ = ' ';
  1828.     t->c = ' ';
  1829.     t->seq = mtree[id].orient ? segment[id].seq : segment[id].rev;
  1830.     t->length = segment[id].length;
  1831.     t->id = id;
  1832.     if ( par != 0 )
  1833.     { 
  1834.         t->s = mtree[id].script;
  1835.         t->size = mtree[id].size;
  1836.     }
  1837.     t->op = 0;
  1838.     for ( i = 1; i <= segment[id].len && i <= NAMELEN; i++ )
  1839.         t->name[i-1] = segment[id].name[i];
  1840.     if ( mtree[id].orient )
  1841.         t->name[i-1] = '+';
  1842.     else
  1843.         t->name[i-1] = '-';
  1844.     t->name[i] = '\0';
  1845.     t->done = 0;
  1846.     t->loc = 1;
  1847.     t->child = 0;
  1848.     t->father = par;
  1849.     if ( par != 0 )
  1850.     { 
  1851.         t->brother = par->child;
  1852.         par->child = t;
  1853.         NEXTOP(t);
  1854.     }
  1855. }
  1856.  
  1857. /* get the next operation */
  1858. NEXTOP(t) rowptr  t;
  1859. {    
  1860.     if ( t->size || t->op )
  1861.         if ( t->op == 0 && *t->s == 0 )
  1862.         { 
  1863.             t->op = *t->s++;
  1864.             t->size--;
  1865.             t->up = 'L';
  1866.             t->dw = 'L';
  1867.         }
  1868.         else
  1869.         { 
  1870.             if ( t->op == 0 )
  1871.             { 
  1872.                 t->op = *t->s++;
  1873.                 t->size--;
  1874.             }
  1875.             if ( t->op > 0 )
  1876.             { 
  1877.                 t->up = '-';
  1878.                 t->dw = 'L';
  1879.                 t->op--;
  1880.             }
  1881.             else
  1882.             { 
  1883.                 t->up = 'L';
  1884.                 t->dw = '-';
  1885.                 t->op++;
  1886.             }
  1887.         }
  1888.     else
  1889.         if ( t->loc > t->length )
  1890.             t->done = 1;
  1891. }
  1892.  
  1893. COLUMN(x) rowptr x;
  1894.     rowptr  y;
  1895.     rowptr  start, end;        /* first and last nodes for subtree */
  1896.  
  1897.     if ( x->child == 0 )
  1898.     { 
  1899.         head = tail = 0;
  1900.         x->kind = 'L';
  1901.     }
  1902.     else
  1903.     { 
  1904.         start = end = 0;
  1905.         x->kind = 'L';
  1906.         for ( y = x->child; y != 0; y = y->brother )
  1907.         { 
  1908.             COLUMN(y);
  1909.             if ( x->kind == y->up )
  1910.                 if ( y->kind == y->dw )
  1911.                 { 
  1912.                     if ( head == 0 )
  1913.                     { 
  1914.                         y->link = 0;
  1915.                         head = tail = y;
  1916.                     }
  1917.                     else
  1918.                     { 
  1919.                         y->link = head;
  1920.                         head = y;
  1921.                     }
  1922.                     if ( end == 0 )
  1923.                         start = head;
  1924.                     else
  1925.                         end->link = head;
  1926.                     end = tail;
  1927.                 }
  1928.                 else
  1929.                     if ( y->kind == '-' )
  1930.                     { 
  1931.                         start = head;
  1932.                         end = tail;
  1933.                         x->kind = '-';
  1934.                     }
  1935.                     else
  1936.                     { 
  1937.                         y->link = 0;
  1938.                         y->kind = '-';
  1939.                         if ( end == 0 )
  1940.                             start = end = y;
  1941.                         else
  1942.                         { 
  1943.                             end->link = y;
  1944.                             end = y;
  1945.                         }
  1946.                     }
  1947.             else
  1948.                 if ( y->kind == y->dw )
  1949.                     if ( x->kind == '-' )
  1950.                         ;
  1951.                     else
  1952.                     { 
  1953.                         if ( head == 0 )
  1954.                         { 
  1955.                             y->link = 0;
  1956.                             head = tail = y;
  1957.                         }
  1958.                         else
  1959.                         { 
  1960.                             y->link = head;
  1961.                             head = y;
  1962.                         }
  1963.                         start = head;
  1964.                         end = tail;
  1965.                         x->kind = '-';
  1966.                     }
  1967.                 else
  1968.                     if ( x->kind == '-' )
  1969.                         if ( y->kind == '-' )
  1970.                         { 
  1971.                             if ( end == 0 )
  1972.                             { 
  1973.                                 start = head;
  1974.                                 end = tail;
  1975.                             }
  1976.                             else
  1977.                                 if ( head == 0 )
  1978. /* code folded from here */
  1979.     ;
  1980. /* unfolding */
  1981.                                 else
  1982.                                 { 
  1983. /* code folded from here */
  1984.     end->link = head;
  1985.     end = tail;
  1986. /* unfolding */
  1987.                                 }
  1988.                         }
  1989.                         else
  1990.                             ;
  1991.                     else
  1992.                     { 
  1993.                         start = head;
  1994.                         end = tail;
  1995.                         x->kind = '-';
  1996.                     }
  1997.         }
  1998.         head = start;
  1999.         tail = end;
  2000.     }
  2001. }
  2002.  
  2003. /* Display a summary of contigs */
  2004. GRAPH()
  2005.     int   i, j, k;        /* index variables */
  2006.     int   group;            /* serial number of contigs  */
  2007.     char name[NAMELEN+2];        /* name of segment */
  2008.     char  *t;            /* temp var */
  2009.     int   length;            /* length of name */
  2010.  
  2011.     (void)    printf("\nOVERLAPS            CONTAINMENTS\n\n");
  2012.     group = 1;
  2013.     for ( i = 0; i < seg_num; i++ )
  2014.         if ( mtree[i].head )
  2015.         { 
  2016.             (void) printf("******************* Contig %d ********************\n",
  2017.                 group++ );
  2018.             for ( j = i; j != -1; j = mtree[j].next )
  2019.             { 
  2020.                 length = segment[j].len;
  2021.                 t = segment[j].name + 1;
  2022.                 for ( k = 0; k < length && k < NAMELEN; k++ )
  2023.                     name[k] = *t++;
  2024.                 if ( mtree[j].orient )
  2025.                     name[k] = '+';
  2026.                 else
  2027.                     name[k] = '-';
  2028.                 name[k+1] = '\0';
  2029.                 (void) printf("%s\n", name);
  2030.                 CONTAIN(mtree[j].child, name);
  2031.             }
  2032.         }
  2033. }
  2034.  
  2035. CONTAIN(id, f) int  id; 
  2036. char *f;
  2037.     int   k;            /* index variable */
  2038.     char name[NAMELEN+2];        /* name of segment */
  2039.     char  *t;            /* temp var */
  2040.     int   length;            /* length of name */
  2041.  
  2042.     if ( id != -1 )
  2043.     { 
  2044.         length = segment[id].len;
  2045.         t = segment[id].name + 1;
  2046.         for ( k = 0; k < length && k < NAMELEN; k++ )
  2047.             name[k] = *t++;
  2048.         if ( mtree[id].orient )
  2049.             name[k] = '+';
  2050.         else
  2051.             name[k] = '-';
  2052.         name[k+1] = '\0';
  2053.         (void) printf("                    %s is in %s\n", name,f);
  2054.         CONTAIN(mtree[id].child, name);
  2055.         CONTAIN(mtree[id].brother, f);
  2056.     }
  2057. }
  2058.  
  2059. big_pass(A,B,M,N,orienti,orientj) char A[],B[]; 
  2060. int  M,N; 
  2061. short orienti, orientj;
  2062.     register  int   i, j;            /* row and column indices */
  2063.     register  int   c;            /* best score at current point */
  2064.     register  int   f;            /* best score ending with insertion */
  2065.     register  int   d;            /* best score ending with deletion */
  2066.     register  int   p;            /* best score at (i-1, j-1) */
  2067.     register  int   ci;            /* end-point associated with c */
  2068.  
  2069.     register  int   di;            /* end-point associated with d */
  2070.     register  int   fi;            /* end-point associated with f */
  2071.     register  int   pi;            /* end-point associated with p */
  2072.     char   *va;                /* pointer to varray(A[i], B[j]) */
  2073.     int   x1, x2;        /* regions of A before x1 or after x2 are lightly penalized */
  2074.     int   y1, y2;        /* regions of B before y1 or after y2 are lightly penalized */
  2075.     short  heavy;        /* 1 = heavy penalty */
  2076.     int   ex, gx;        /* current gap penalty scores */
  2077.  
  2078.     /* determine x1, x2, y1, y2 */
  2079.     if ( POS5 >= POS3 )
  2080.         fatal("The value for POS5 must be less than the value for POS3");
  2081.     if ( orienti )
  2082.     { 
  2083.         x1 = POS5 >= M ? 1 : POS5;
  2084.         x2 = POS3 >= M ? M : POS3;
  2085.     }
  2086.     else
  2087.     { 
  2088.         x1 = POS3 >= M ? 1 : M - POS3 + 1;
  2089.         x2 = POS5 >= M ? M : M - POS5 + 1;
  2090.     }
  2091.     if ( orientj )
  2092.     { 
  2093.         y1 = POS5 >= N ? 1 : POS5;
  2094.         y2 = POS3 >= N ? N : POS3;
  2095.     }
  2096.     else
  2097.     { 
  2098.         y1 = POS3 >= N ? 1 : N - POS3 + 1;
  2099.         y2 = POS5 >= N ? N : N - POS5 + 1;
  2100.     }
  2101.     if ( x1 + 1 <= x2 ) x1++;
  2102.     if ( y1 + 1 <= y2 ) y1++;
  2103.     heavy = 0;
  2104.  
  2105.     /* Compute the matrix.
  2106.        CC : the scores of the current row
  2107.        RR : the starting point that leads to score CC
  2108.        DD : the scores of the current row, ending with deletion
  2109.        SS : the starting point that leads to score DD        */
  2110.     /* Initialize the 0 th row */
  2111.     for ( j = 1; j <= N ; j++ )
  2112.     {  
  2113.         CC[j] = 0;
  2114.         DD[j] = - (q);
  2115.         RR[j] = SS[j] = -j;
  2116.     }
  2117.     for ( i = 1; i <= M; i++)
  2118.     {  
  2119.         if ( i == x1 ) heavy = 1 - heavy;
  2120.         if ( i == x2 ) heavy = 1 - heavy;
  2121.         ex = r1;
  2122.         gx = qr1;
  2123.         va = v1[A[i]];
  2124.         c = 0;                /* Initialize column 0 */
  2125.         f = - (q);
  2126.         ci = fi = i;
  2127.         p = 0;
  2128.         pi = i - 1;
  2129.         for ( j = 1 ; j <= N ; j++ )
  2130.         {  
  2131.             if ( j == y1 )
  2132.             { 
  2133.                 if ( heavy )
  2134.                 { 
  2135.                     ex = r;
  2136.                     gx = qr;
  2137.                     /*
  2138. S.S.
  2139.                     va = varray[A[i]];
  2140. */
  2141.                     va = varray[A[i]];
  2142.                 }
  2143.             }
  2144.             if ( j == y2 )
  2145.             { 
  2146.                 if ( heavy )
  2147.                 { 
  2148.                     ex = r1;
  2149.                     gx = qr1;
  2150.                     va = v1[A[i]];
  2151.                 }
  2152.             }
  2153.             if ( ( f = f - ex ) < ( c = c - gx ) )
  2154.             { 
  2155.                 f = c; 
  2156.                 fi = ci; 
  2157.             }
  2158.             di = SS[j];
  2159.             if ( ( d = DD[j] - ex ) < ( c = CC[j] - gx ) )
  2160.             { 
  2161.                 d = c; 
  2162.                 di = RR[j]; 
  2163.             }
  2164.             c = p+va[B[j]];        /* diagonal */
  2165.             ci = pi;
  2166.             if ( c < d )
  2167.             { 
  2168.                 c = d; 
  2169.                 ci = di; 
  2170.             }
  2171.             if ( c < f )
  2172.             { 
  2173.                 c = f; 
  2174.                 ci = fi; 
  2175.             }
  2176.             p = CC[j];
  2177.             CC[j] = c;
  2178.             pi = RR[j];
  2179.             RR[j] = ci;
  2180.             DD[j] = d;
  2181.             SS[j] = di;
  2182.             if ( ( j == N || i == M ) &&  c > SCORE )
  2183.             { 
  2184.                 SCORE = c;
  2185.                 ENDI = i;
  2186.                 ENDJ = j;
  2187.                 STARI = ci;
  2188.             }
  2189.         }
  2190.     }
  2191.     if ( SCORE )
  2192.         if ( STARI < 0 )
  2193.         { 
  2194.             STARJ = - STARI;
  2195.             STARI = 0;
  2196.         }
  2197.         else
  2198.             STARJ = 0;
  2199. }
  2200.  
  2201. /* diff(A,B,M,N,tb,te) returns the score of an optimum conversion between
  2202.    A[1..M] and B[1..N] that begins(ends) with a delete if tb(te) is zero
  2203.    and appends such a conversion to the current script.                   */
  2204.  
  2205. int  diff(A,B,M,N,tb,te) char *A, *B; 
  2206. int  M, N; 
  2207. int  tb, te;
  2208.  
  2209.     int    midi, midj, type;    /* Midpoint, type, and cost */
  2210.     int  midc;
  2211.  
  2212.     { 
  2213.         register int    i, j;
  2214.         register int  c, e, d, s;
  2215.         int  t;
  2216.         char    *va;
  2217.         char  *ckalloc();
  2218.  
  2219.         /* Boundary cases: M <= 1 or N == 0 */
  2220.  
  2221.         if (N <= 0)
  2222.         { 
  2223.             if (M > 0) DEL(M)
  2224.                 return - gap(M);
  2225.         }
  2226.         if (M <= 1)
  2227.         { 
  2228.             if (M <= 0)
  2229.             { 
  2230.                 INS(N);
  2231.                 return - gap(N);
  2232.             }
  2233.             if (tb > te) tb = te;
  2234.             midc = - (tb + r + gap(N) );
  2235.             midj = 0;
  2236.             va = varray[A[1]];
  2237.             for (j = 1; j <= N; j++)
  2238.             { 
  2239.                 c = va[B[j]] - ( gap(j-1) + gap(N-j) );
  2240.                 if (c > midc)
  2241.                 { 
  2242.                     midc = c;
  2243.                     midj = j;
  2244.                 }
  2245.             }
  2246.             if (midj == 0)
  2247.             { 
  2248.                 INS(N) DEL(1)             }
  2249.             else
  2250.             { 
  2251.                 if (midj > 1) INS(midj-1)
  2252.                     REP
  2253.                         if ( (A[1]|32) == (B[midj]|32) )
  2254.                         no_mat += 1;
  2255.                     else
  2256.                         no_mis += 1;
  2257.                 if (midj < N) INS(N-midj)
  2258.             }
  2259.             return midc;
  2260.         }
  2261.  
  2262.         /* Divide: Find optimum midpoint (midi,midj) of cost midc */
  2263.  
  2264.         midi = M/2;            /* Forward phase:                          */
  2265.         CC[0] = 0;            /*   Compute C(M/2,k) & D(M/2,k) for all k */
  2266.         t = -q;
  2267.         for (j = 1; j <= N; j++)
  2268.         { 
  2269.             CC[j] = t = t-r;
  2270.             DD[j] = t-q;
  2271.         }
  2272.         t = -tb;
  2273.         for (i = 1; i <= midi; i++)
  2274.         { 
  2275.             s = CC[0];
  2276.             CC[0] = c = t = t-r;
  2277.             e = t-q;
  2278.             va = varray[A[i]];
  2279.             for (j = 1; j <= N; j++)
  2280.             { 
  2281.                 if ((c = c - qr) > (e = e - r)) e = c;
  2282.                 if ((c = CC[j] - qr) > (d = DD[j] - r)) d = c;
  2283.                 c = s+va[B[j]];
  2284.                 if (c < d) c = d;
  2285.                 if (c < e) c = e;
  2286.                 s = CC[j];
  2287.                 CC[j] = c;
  2288.                 DD[j] = d;
  2289.             }
  2290.         }
  2291.         DD[0] = CC[0];
  2292.  
  2293.         RR[N] = 0;            /* Reverse phase:                          */
  2294.         t = -q;            /*   Compute R(M/2,k) & S(M/2,k) for all k */
  2295.         for (j = N-1; j >= 0; j--)
  2296.         { 
  2297.             RR[j] = t = t-r;
  2298.             SS[j] = t-q;
  2299.         }
  2300.         t = -te;
  2301.         for (i = M-1; i >= midi; i--)
  2302.         { 
  2303.             s = RR[N];
  2304.             RR[N] = c = t = t-r;
  2305.             e = t-q;
  2306.             va = varray[A[i+1]];
  2307.             for (j = N-1; j >= 0; j--)
  2308.             { 
  2309.                 if ((c = c - qr) > (e = e - r)) e = c;
  2310.                 if ((c = RR[j] - qr) > (d = SS[j] - r)) d = c;
  2311.                 c =  s+va[B[j+1]];
  2312.                 if (c < d) c = d;
  2313.                 if (c < e) c = e;
  2314.                 s = RR[j];
  2315.                 RR[j] = c;
  2316.                 SS[j] = d;
  2317.             }
  2318.         }
  2319.         SS[N] = RR[N];
  2320.  
  2321.         midc = CC[0]+RR[0];        /* Find optimal midpoint */
  2322.         midj = 0;
  2323.         type = 1;
  2324.         for (j = 0; j <= N; j++)
  2325.             if ((c = CC[j] + RR[j]) >= midc)
  2326.                 if (c > midc || CC[j] != DD[j] && RR[j] == SS[j])
  2327.                 { 
  2328.                     midc = c;
  2329.                     midj = j;
  2330.                 }
  2331.         for (j = N; j >= 0; j--)
  2332.             if ((c = DD[j] + SS[j] + q) > midc)
  2333.             { 
  2334.                 midc = c;
  2335.                 midj = j;
  2336.                 type = 2;
  2337.             }
  2338.     }
  2339.  
  2340.     /* Conquer: recursively around midpoint */
  2341.  
  2342.     if (type == 1)
  2343.     {
  2344.         (void) diff(A,B,midi,midj,tb,q);
  2345.         (void) diff(A+midi,B+midj,M-midi,N-midj,q,te);
  2346.     }
  2347.     else
  2348.     {
  2349.         (void) diff(A,B,midi-1,midj,tb,zero);
  2350.         DEL(2);
  2351.         (void) diff(A+midi+1,B+midj,M-midi-1,N-midj,zero,te);
  2352.     }
  2353.     return midc;
  2354. }
  2355.  
  2356. /* lib.c - library of C procedures. */
  2357.  
  2358. /* fatal - print message and die */
  2359. fatal(msg)
  2360. char *msg;
  2361. {
  2362.     (void) fprintf(stderr, "%s\n", msg);
  2363.     exit(1);
  2364. }
  2365.  
  2366. /* fatalf - format message, print it, and die */
  2367. fatalf(msg, val)
  2368. char *msg, *val;
  2369. {
  2370.     (void) fprintf(stderr, msg, val);
  2371.     (void)    putc('\n', stderr);
  2372.     exit(1);
  2373. }
  2374.  
  2375. /* ckopen - open file; check for success */
  2376. FILE *ckopen(name, mode)
  2377. char *name, *mode;
  2378. {
  2379.     FILE *fopen(), *fp;
  2380.  
  2381.     if ((fp = fopen(name, mode)) == NULL)
  2382.         fatalf("Cannot open %s.", name);
  2383.     return(fp);
  2384. }
  2385.  
  2386. /* ckalloc - allocate space; check for success */
  2387. char *ckalloc(amount)
  2388. int  amount;
  2389. {
  2390.     char *p;
  2391.  
  2392.     if ((p = (char*) malloc( (unsigned) amount)) == NULL)
  2393.         fatal("Ran out of memory.");
  2394.     return(p);
  2395. }
  2396.  
  2397.